#include<iostream>
#include<stdio.h>
#include<pthread.h>
#include<cassert>
#include<unistd.h>

// ps -aL:可以查看轻量级进程的选项
// LWP:light weight process:轻量级进程

using namespace std;

int g_val = 0;

void fun()
{
    cout << "我是一个独立的方法" << endl;
}
// 新线程
void* thread_routine(void* args)
{
    const char* name = (const char*)args;
    while(1)
    {
    cout << "我是新线程，我正在运行！name: " << name << " : "<< g_val++ << "  &g_val: " << &g_val << endl;
    fun();
    sleep(1);
    }
}
int main()
{
    pthread_t tid;
    // void *(*start_routine) (void *)
    int n = pthread_create(&tid,nullptr,thread_routine,(void*)"thread one");// routine:程序
    assert(n == 0);
    (void)n;

    // 主线程
    while(true)
    {
        // 地址 ？？
        char tidbuffer[64];
        snprintf(tidbuffer,sizeof(tidbuffer),"0x%x",tid);//%x:16进制

        cout << "我是主线程，我正在运行！,我创建出来的线程的tid： " << tidbuffer << " : "<< g_val << "  &g_val: " << &g_val << endl;
        fun();
        sleep(1);
    }
    return 0;
}



//////////////////////////////////////////////////线程////////////////////////////////////////////

// 如何看待虚存：虚拟内存里面决定了进程能看到的"资源"

// CPU:只关注task_struct 轻量级进程
// 线程：进程内的一个执行流
// 1.线程在进程内部运行，线程在进程的地址空间内运行！拥有该进程的一部分资源！

// 1.什么叫进程？？ 内核视角：承担分配系统资源的基本实体(task_struct + 虚拟内存 + 页表 + 物理内存)
// 1.1在liunx中，什么叫做线程呢？ CPU调度的基本单位！
// 2.以前学的进程：承担系统资源部的基本实体，只不过，内部只有一个执行流！！一个进程内部可以有多个执行流

// 因为我们可以通过虚拟地址空间+页表方式对进程进行资源划分，单个"进程"执行力度一定比之前的进程要细
// "线程"也要被OS管理，先描述，在组织。 --> Windows:位线程专门设计数据结构表示线程对象，TCB。
// 单从线程调度角度，线程和进程有很多地方是重叠的！
// 所以，Linux工程师，不想给"线程"专门设计对应的数据结构！而是直接复用PCB！用PCB用来表示Liunx内部的"线程"

// 1.Liunx内核中没有真正意义的线程。Liunx是用进程PCB来模拟线程的，是一种完全属于自己的一套方案
// 2.站在CPU的时间，每一个PCB，都可以成为叫做轻量级进程
// 3.Linux线程是CPU调度的基本单位，为进程是承担分配系统资源的基本单位
// 4.进程用来整体申请资源，线程用来伸手向进程要资源
// 5.Linux中没有真正意义的线程
// OS只认线程，用户(程序员)也只认线程 --> Linux便无法提供创建线程的系统调用接口！而我们只能提供创建轻量级进程的接口！ --> clone() vfork()
// 用户和系统间，Linux提供了一个用户级线程库，任何Linux操作系统，都必须默认携带这个库的原生线程库
// 6.好处是什么？简单，维护成本大大降低  -- 可靠高效

// 1.如何理解？
// 家庭：进程 家庭成员：线程

// 线程一旦被创建，几乎所有的资源都是被所有线程共享的！！
// 线程也一定要有自己私有的资源，什么资源应该是线程私有的呢？
// 1.PCB属性私有
// 2.要有一定私有上下文结构
// 3.每一个线程都要有自己独立的栈结构

// 优点：
// 与进程之间的切换相比，线程之间的切换需要操作系统做的工作少很多
// 1. 进程：切换页表 && 虚拟地址空间 && 切换PCB && 上下文切换
// 2. 线程：切换PCB && 上下文切换
// CPU内还有一个集成的寄存器：cache -- 高速缓存 -- 局部性原理 -- 寄存器从cach读数据
// 寄存器往cache读数据，cache往内存读数据
// 3.线程切换cache不用态更新，但是进程切换，全部更新
// 计算密集型应用，为了能在多处理器系统上运行，将计算分解到多个线程中实现
// I/O密集型应用，为了提高性能，将I/O操作重叠。线程可以同时等待不同的I/O操作。

// CPU调度的时候，是以哪一个id为标识符表示特定一个执行流呢？ LWP
// 以前只有一个执行流的时候， PID == LWP ，是等价的
// 发送信号，是给整个进程发送信号的

////////////////////////////////////////////函数接口///////////////////////////////////////////////////

//创建轻量级线程
// #include <pthread.h>
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
// pthread_t *thread：线程id  const pthread_attr_t *attr：不用管，设为NULL  void *(*start_routine) (void *)：回调方法  void *arg：回调方法的参数
// Compile and link with -pthread.   --> 轻量级线程是第三方线程库提供给我们的
